package com.example.agrigreennewssys.lucene;


import com.example.agrigreennewssys.dto.ArticleDetailDTO;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;

/**
 * @author 光的代言人
 */
@Service
public class LuceneSearchService {

    @Value("${spring.lucene.index-dir}")
    private String indexDir;

    public List<ArticleDetailDTO> search(String queryString) throws Exception {
        Directory directory = FSDirectory.open(Paths.get(indexDir));
        IndexReader reader = DirectoryReader.open(directory);
        IndexSearcher searcher = new IndexSearcher(reader);
        Analyzer analyzer = new SmartChineseAnalyzer();

        // 定义搜索字段及权重（包含作者名和标签）
        String[] fields = {"title", "content"};
        Map<String, Float> boosts = new HashMap<>();
        boosts.put("title", 2.0f);
        boosts.put("content", 1.0f);
//        boosts.put("authorName", 1.2f);
//        boosts.put("tags", 1.0f);

        // 构建查询
        QueryParser parser = new MultiFieldQueryParser(fields, analyzer, boosts);
        Query query = parser.parse(queryString);
        TopDocs topDocs = searcher.search(query, 10);

        // 初始化高亮组件
        SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<b><font color='#22C55E'>", "</font></b>");
        QueryScorer scorer = new QueryScorer(query);
        Highlighter highlighter = new Highlighter(formatter, scorer);
        highlighter.setTextFragmenter(new SimpleSpanFragmenter(scorer, 100)); // 片段长度100字符

        List<ArticleDetailDTO> results = new ArrayList<>();
        for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
            Document doc = searcher.doc(scoreDoc.doc);
            results.add(convertToHomeArticle(doc, analyzer, highlighter));
        }
        reader.close();
        return results;
    }

    // 高亮处理核心方法
    private ArticleDetailDTO convertToHomeArticle(Document doc, Analyzer analyzer, Highlighter highlighter) {
        try {
            // 确保关键字段存在且非空
            String articleId = getFieldValue(doc, "articleId", true); // 强制要求id存在
            String rawTitle = getFieldValue(doc, "title", false);
            String rawContent = getFieldValue(doc, "content", false);
            String nickName = getFieldValue(doc, "nickName", false);
            String tagName = getFieldValue(doc, "tagName", false);
            String avatarUrl = getFieldValue(doc, "avatarUrl", false);
            String createdAt = getFieldValue(doc, "createdAt", false);

            // 高亮处理
            String highlightedTitle = getHighlightedText(highlighter, analyzer, "title", rawTitle);
            String highlightedContent = getHighlightedText(highlighter, analyzer, "content", rawContent);
            if (rawContent.length() >= 100) {
                rawContent= rawContent.substring(0, 100);
            }


            ArticleDetailDTO articleDetailDTO=new ArticleDetailDTO();
            articleDetailDTO.setArticleId( Long.parseLong(articleId));
            articleDetailDTO.setContent(highlightedContent != null ? highlightedContent : rawContent);
            articleDetailDTO.setTitle( highlightedTitle != null ? highlightedTitle : rawTitle);
            articleDetailDTO.setAvatarUrl(avatarUrl);
            articleDetailDTO.setCreatedAt(createdAt);
            articleDetailDTO.setNickName(nickName);
            articleDetailDTO.setTagName(tagName);

            return articleDetailDTO;
        } catch (Exception e) {
            throw new RuntimeException("文档转换失败: " + e.getMessage() + ", 文档内容: " + doc.toString(), e);
        }
    }


    private String getFieldValue(Document doc, String field, boolean required) {
        String value = doc.get(field);
        if (required && (value == null || value.isEmpty())) {
            throw new IllegalArgumentException("字段 [" + field + "] 不存在或为空");
        }
        return value;
    }

    private int parseInteger(String value, int defaultValue) {
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    // 高亮工具方法
    private String getHighlightedText(Highlighter highlighter, Analyzer analyzer, String field, String text)
            throws IOException, InvalidTokenOffsetsException {
        if (text == null) {
            return null;
        }
        try (TokenStream tokenStream = analyzer.tokenStream(field, text)) {
            return highlighter.getBestFragment(tokenStream, text);
        }
    }
}